package cn.com.weather.nf.controller;

import java.io.Serializable;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import cn.com.weather.nf.entity.TemplateInstances;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;

import cn.com.weather.nf.entity.RecordForm;
import cn.com.weather.nf.entity.RecordWeather;
import cn.com.weather.nf.service.BaseOperateService;
import cn.com.weather.nf.service.JcbcService;
import cn.com.weather.nf.util.NameUtil;
import cn.com.weather.nf.vo.BeanResult;
import cn.com.weather.nf.vo.ListResult;

@RestController
@RequestMapping(value = "/v1")
public class SunAppController {

    private static final Logger LOGGER = LoggerFactory.getLogger(SunAppController.class);


    private static final String BEAN_PACKAGE_PREFIX = "cn.com.weather.nf.entity.";
    private static final String LOG_EXCEPTION = "exception : {}";

    @Autowired
    private BaseOperateService baseOperateService;
    
    @Autowired
    private JcbcService jcbcService;


    private String assemblyClassName(String beanNameWithUnderline) {

        return NameUtil.humpName(beanNameWithUnderline);
    }

    @RequestMapping(value="/sun-app/{beanName}", method = RequestMethod.POST)
    public BeanResult save(@PathVariable(value="beanName") String beanName,
                           @RequestBody String inputJson,
                           HttpServletRequest request) {

        BeanResult result = null;

        try {
            String className = this.assemblyClassName(beanName);

            Class<?> beanClass = Class.forName(BEAN_PACKAGE_PREFIX + className);
            Serializable data = (Serializable) JSONObject.parseObject(inputJson, beanClass);

            this.baseOperateService.save(data);
            result = BeanResult.success("OK");

        } catch (Exception e) {
            LOGGER.warn(LOG_EXCEPTION, e);
            result = BeanResult.error(e.getMessage());
        }
        return result;
    }

    /**
     * 记录评分
     * @param id
     * @param inputJson
     * @param request
     * @return
     */
    private BeanResult updateRecordForm( BeanResult beanResult, Long id) {
        
        LOGGER.debug("raw invoke: /record_form/{}", id);
        if (beanResult.getStatus().equals(BeanResult.FLAG_OF_SUCCESS)) {
            RecordForm recordForm = (RecordForm) beanResult.getData();
            this.jcbcService.updateOrAddRecordFormScoure(recordForm);
        }
        
        return beanResult;
    }
    
    /** 
     * 记录评分
     * @param id
     * @param inputJson
     * @param request
     * @return
     */
    private BeanResult updateRecordWeather( BeanResult beanResult, Long id) {
        
        LOGGER.debug("raw invoke: /record_weather/{}", id);
        
        if (beanResult.getStatus().equals(BeanResult.FLAG_OF_SUCCESS)) {
            RecordWeather recordWeather = (RecordWeather) beanResult.getData();
            this.jcbcService.updateOrAddRecordWeatherScoure(recordWeather);
        }
        return beanResult;
    }
    
    
    /**
     * 修改数据
     * @param beanName
     * @param id
     * @param inputJson
     * @param request
     * @return
     */
    @RequestMapping(value="/sun-app/{beanName}/{id}", method = RequestMethod.PUT)
    public BeanResult update(@PathVariable(value="beanName") String beanName,
                            @PathVariable(value="id") Long id,
                           @RequestBody String inputJson,
                           HttpServletRequest request) {

        BeanResult result = null;

        try {
            String className = this.assemblyClassName(beanName);

            Class<?> beanClass = Class.forName(BEAN_PACKAGE_PREFIX + className);
            Serializable data = (Serializable) JSONObject.parseObject(inputJson, beanClass);

            LOGGER.debug("PUT A data : {}", data);

            Object updated = this.baseOperateService.update(data, id);
            LOGGER.debug("updat result : {}", updated);
            LOGGER.debug("beanName : {}", beanName);
            
            if (updated != null) {
                result = BeanResult.success(updated);
                if ("record_weather".equals(beanName)) {
                    this.updateRecordWeather(result, id);
                } else if ("record_form".equals(beanName)) {
                    this.updateRecordForm(result, id);
                }
            } else {
                result = BeanResult.error("无数据");
            }

        } catch (Exception e) {
            LOGGER.warn(LOG_EXCEPTION, e);
            result = BeanResult.error(e.getMessage());
        }
        return result;
    }


    @RequestMapping(value="/sun-app/ip")
    public String getIpAddress(HttpServletRequest request) {

        return this.getIp(request);

    }


    private String getIp(HttpServletRequest request) {

        LOGGER.debug("remote-addr : {}", request.getRemoteAddr());
        LOGGER.debug("remote-host : {}", request.getRemoteHost());
        LOGGER.debug("remote-port : {}", request.getRemotePort());
        LOGGER.debug("remote-user : {}", request.getRemoteUser());

        return request.getRemoteAddr();

    }


    @RequestMapping(value="/sun-app/{beanName}/{id}", method = RequestMethod.GET)
    public BeanResult query(@PathVariable(value="beanName") String beanName,
                            @PathVariable(value="id") Long id) {

        BeanResult result = null;
        try {
            String className = this.assemblyClassName(beanName);
            Class<?> beanClass = Class.forName(BEAN_PACKAGE_PREFIX + className);
            Object data = this.baseOperateService.findById(beanClass, id);
            result = BeanResult.success(data);
        } catch (Exception e) {
            LOGGER.warn(LOG_EXCEPTION, e);
            result = BeanResult.error(e.getMessage());
        }
        return result;
    }


    @RequestMapping(value="/sun-app/{beanName}/{id}", method = RequestMethod.DELETE)
    public BeanResult delete(@PathVariable(value="beanName") String beanName,
                             @PathVariable(value="id") Long id) {

        BeanResult result = null;

        try {
            String className = this.assemblyClassName(beanName);
            Class<?> beanClass = Class.forName(BEAN_PACKAGE_PREFIX + className);

            this.baseOperateService.delete(beanClass, id);

            result = BeanResult.success("OK");
        } catch (Exception e) {
            LOGGER.warn(LOG_EXCEPTION, e);
            result = BeanResult.error(e.getMessage());
        }
        return result;
    }

    /**
     * record_form   需要增加 type 
     * type 关联到 template_instances 中的 type
     * 
     * @param type
     * @param current
     * @param pageSize
     * @return
     */
    @RequestMapping(value="/sun-app/record_form", method = RequestMethod.GET)
    @ResponseBody
    public BeanResult
    queryRecordRorm(@RequestParam(value="type") String type,
                    @RequestParam(value="from") String from,
                    @RequestParam(value="current", defaultValue = "1") Integer current,
                    @RequestParam(value="pageSize", defaultValue = "20") Integer pageSize,
                    @RequestParam(value="instanceId", defaultValue = "-1") Integer instanceId,
                    @RequestParam(value="search", defaultValue = "") String search,
                    @RequestParam(value="begin", defaultValue = "") String begin,
                    @RequestParam(value="end", defaultValue = "") String end) {
        
        BeanResult result = null;
        
        if (!StringUtils.hasText(type)) {
            return BeanResult.error("type 值不能为空。");
        }
        if (!StringUtils.hasText(from)) {
            return BeanResult.error("from 值不能为空。");
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");

        Date date;
        long beginTime = 0;
        long endTime = System.currentTimeMillis() + 1000; //

        if (!StringUtils.isEmpty(begin)) {
            try {
                date = sdf.parse(begin);
                beginTime = date.getTime();
            } catch (ParseException e) {
            }
        }

        if (!StringUtils.isEmpty(end)) {
            try {
                date = sdf.parse(end);
                endTime = date.getTime();
            } catch (ParseException e) {
            }
        }

        try {
   
            ListResult data = this.baseOperateService
                    .findRecordFormPagination(type, from, current, pageSize, instanceId, search, beginTime, endTime);

            result = BeanResult.success(data);
        } catch (Exception e) {
            LOGGER.warn(LOG_EXCEPTION, e);
            result = BeanResult.error(e.getMessage());
        }
        return result;
    }
    
    /**
     * 
     * @param current
     * @param pageSize
     * @return
     */
    @RequestMapping(value="/sun-app/record_weather", method = RequestMethod.GET)
    @ResponseBody
    public BeanResult queryRecordWeather(
            @RequestParam(value="from", defaultValue="") String from,
            @RequestParam(value="current", defaultValue = "1") Integer current,
            @RequestParam(value="pageSize", defaultValue = "20") Integer pageSize
            ) {
        
        BeanResult result = null;
        
        if (!StringUtils.hasText(from)) {
            return BeanResult.error("from 值不能为空。");
        }
        
        try {
            
            ListResult data = this.baseOperateService.findRecordWeatherPagination(from, current, pageSize);

            result = BeanResult.success(data);
        } catch (Exception e) {
            LOGGER.warn(LOG_EXCEPTION, e);
            result = BeanResult.error(e.getMessage());
        }
        return result;
    }
    



    @RequestMapping(value="/sun-app/{beanName}",
            method = RequestMethod.GET)
    public BeanResult queryList(@PathVariable(value = "beanName") String beanName,
                                @RequestParam(value="current", defaultValue = "1") Integer current,
                                @RequestParam(value="pageSize", defaultValue = "20") Integer pageSize
                                ) {

        BeanResult result = null;
        try {
            String className = this.assemblyClassName(beanName);
            Class<?> beanClass = Class.forName(BEAN_PACKAGE_PREFIX + className);

            ListResult data = this.baseOperateService.findPagination(beanClass, current, pageSize);

            result = BeanResult.success(data);
        } catch (Exception e) {
            LOGGER.warn(LOG_EXCEPTION, e);
            result = BeanResult.error(e.getMessage());
        }
        return result;
    }


    @RequestMapping(value="/sun-app/template-instances", method = RequestMethod.GET)
    @ResponseBody
    public BeanResult getAllTemplateInstances(@RequestParam(value="type", defaultValue = "wenti") String type) {

        List<TemplateInstances> instancesList = this.baseOperateService.findAllTemplateInstances(type);

        return BeanResult.success(instancesList);
    }
}
